/**
 * 获取地址栏参数
 * @return {Object}
 */
function getRequest() {
  let url = window.location.search; //获取url中"?"符后的字串
  let theRequest = new Object();
  if (url.indexOf("?") != -1) {
    let str = url.substr(1);
    let strs = str.split("&");
    for (let i = 0; i < strs.length; i++) {
      theRequest[strs[i].split("=")[0]] = decodeURI(strs[i].split("=")[1]);
    }
  }
  return theRequest;
}

/**
 * 获取地址栏参数
 * @param {String} name 参数名
 * @return {String} 返回参数值
 */
export const getQueryString = (name) => {
  let reg = new RegExp("(^|&)" + name + "=([^&]*)(&|$)");
  let r = window.location.search.substr(1).match(reg);
  if (r != null) return unescape(r[2]);
  return null;
};

/**
 * 存储localStorage
 * @param {String} name
 * @param {String or Object} content
 */
function setLocalStore(name, content) {
  if (!name) return;
  if (typeof content !== 'string') {
    content = JSON.stringify(content);
  }
  window.localStorage.setItem(name, content);
}

/**
 * 获取localStorage
 * @param {String} name
 * @return {Object}
 */
function getLocalStore(name) {
  if (!name) return;
  return window.localStorage.getItem(name);
}

/**
 * 删除localStorage
 * @param {String} name
 */
function removeLocalStore(name) {
  if (!name) return;
  window.localStorage.removeItem(name);
}

/**
 * 清空localStorage
 */
function clearLocalStore() {
  if (!name) return;
  window.localStorage.clear();
}

/**
 * 判断是否为手机号
 * @param {String} str
 * @return {Boolean}
 */
function isPoneAvailable(str) {
  let myreg = /^[1][3,4,5,6,7,8][0-9]{9}$/;
  if (!myreg.test(str)) {
    return false;
  } else {
    return true;
  }
}

/**
 * 判断是否微信 是不是微信浏览器
 * @return {Boolean}
 */
function isWeiXin() {
  let ua = window.navigator.userAgent.toLowerCase();
  if (ua.match(/MicroMessenger/i) == 'micromessenger') {
    return true;
  } else {
    return false;
  }
}

/**
 * 判断是安卓还是ios
 * @return {Boolean} false=>ios, true=>安卓
 */
function isAndroid() {
  let ua = navigator.userAgent.toLowerCase();
  if (/iphone|ipad|ipod/.test(ua)) {
    return false;
  } else if (/android/.test(ua)) {
    return true;
  }
}

/**
 * 判断当前设备是移动端还是pc端
 * @return {Boolean} true pc端; false 移动端
 */
export const IsPC = () => {
  var userAgentInfo = navigator.userAgent;
  var Agents = ["Android", "iPhone", "SymbianOS", "Windows Phone", "iPad", "iPod"];
  var sum = 0;
  for (var v = 0; v < Agents.length; v++) {
    if (parseFloat(userAgentInfo.indexOf(Agents[v])) > 0) {
      sum++;
    }
  }
  if (sum > 0) {//移动端
    return false
  } else {//PC端
    return true
  }
}

/**
 * 计算字符长度 汉字算两个字符
 * @param {String} val
 * @return {Number} 返回字符长度
 */
function getByteLen(val) {
  let len = 0;
  for (let i = 0; i < val.length; i++) {
    let length = val.charCodeAt(i);
    if (length >= 0 && length <= 128) {
      len += 1;
    } else {
      len += 2;
    }
  }
  return len;
}

/**
 * 分割视频时间 00:14
 * @param {Number} second_time 视频时长
 * @return {String} 返回格式 00:14
 */
function timeStamp(second_time) {
  let time1 = ((parseInt(second_time) / 100)).toString();
  let time2 = time1.split(".")[1] ? (time1.split(".")[1].length == 1 ? time1.split(".")[1] + '0' : time1.split(".")[1]) : '00';
  let time = '00' + ':' + time2;
  if (parseInt(second_time) > 60) {
    let second = ((parseInt(second_time) % 60) / 100).toString();
    let min = (parseInt(second_time / 60) / 100).toString();
    let time3 = second.split(".")[1] ? (second.split(".")[1].length == 1 ? second.split(".")[1] + '0' : second.split(".")[1]) : '00';
    let time4 = min.split(".")[1] ? (min.split(".")[1].length == 1 ? min.split(".")[1] + '0' : min.split(".")[1]) : '00';
    time = time4 + ":" + time3;
  }
  return time;
}

/**
 * 显示的金额带“ ，”分隔符并保留2位小数10000 => 10,000.00;
 * @param {Number} num 金额
 * @param {Number} precision 保留几位小数，默认0位
 * @param {String} separator 分隔符，默认“ ， ”
 * @return {String}
 */
function formatNumber(num, precision, separator) {
  let parts;
  // 判断是否为数字
  if (!isNaN(parseFloat(num)) && isFinite(num)) {
    // 把类似 .5, 5. 之类的数据转化成0.5, 5, 为数据精度处理做准, 至于为什么
    // 不在判断中直接写 if (!isNaN(num = parseFloat(num)) && isFinite(num))
    // 是因为parseFloat有一个奇怪的精度问题, 比如 parseFloat(12312312.1234567119)
    // 的值变成了 12312312.123456713
    num = Number(num);
    // 处理小数点位数
    num = (typeof precision !== 'undefined' ? num.toFixed(precision) : num).toString();
    // 分离数字的小数部分和整数部分
    parts = num.split('.');
    // 整数部分加[separator]分隔, 借用一个著名的正则表达式
    parts[0] = parts[0].toString().replace(/(\d)(?=(\d{3})+(?!\d))/g, '$1' + (separator || ','));
    return parts.join('.');
  }
  return NaN;
}

/******************密码强度验证*****************/
/**
 * 判断输入密码的类型
 * @param {Number} iN Unicode编码
 * @return {Number}
 */
function CharMode(iN) {
  if (iN >= 48 && iN <= 57) //数字
    return 1;
  if (iN >= 65 && iN <= 90) //大写
    return 2;
  if (iN >= 97 && iN <= 122) //小写
    return 4;
  else
    return 8;
}

/**
 * bitTotal函数 计算密码模式
 * @param {Number} num
 * @return {Number}
 */
function bitTotal(num) {
  let modes = 0;
  for (let i = 0; i < 4; i++) {
    if (num & 1) modes++;
    num >>>= 1;
  }
  return modes;
}

/**
 * 返回密码强度级别
 * @param {String} sPW 密码
 * @return {Number} 0 1 2 3
 */
function checkStrong(sPW) {
  if (sPW.length < 6)
    return 0; //密码太短，不检测级别
  let Modes = 0;
  for (let i = 0; i < sPW.length; i++) {
    //密码模式
    Modes |= CharMode(sPW.charCodeAt(i));
  }
  return bitTotal(Modes);
}

/**
 * 检测浏览器是否支持flash
 * @return {Boolean}
 */
function flashChecker() {
  let flag = false;
  if (window.ActiveXObject) {
    try {
      let swf = new ActiveXObject("ShockwaveFlash.ShockwaveFlash");
      if (swf) {
        flag = true;
      }
    } catch (e) {
    }
  } else {
    try {
      let swf = navigator.plugins['Shockwave Flash'];
      if (swf) {
        flag = true;
      }
    } catch (e) {
    }
  }
  return flag;
}

/**
 * 身份证号合法性验证
 * 支持15位和18位身份证号
 * 支持地址编码、出生日期、校验位验证
 * @param {String} code
 * @return {Boolean}
 */
function identityCodeValid(code) {
  let city = {
    11: "北京",
    12: "天津",
    13: "河北",
    14: "山西",
    15: "内蒙古",
    21: "辽宁",
    22: "吉林",
    23: "黑龙江 ",
    31: "上海",
    32: "江苏",
    33: "浙江",
    34: "安徽",
    35: "福建",
    36: "江西",
    37: "山东",
    41: "河南",
    42: "湖北 ",
    43: "湖南",
    44: "广东",
    45: "广西",
    46: "海南",
    50: "重庆",
    51: "四川",
    52: "贵州",
    53: "云南",
    54: "西藏 ",
    61: "陕西",
    62: "甘肃",
    63: "青海",
    64: "宁夏",
    65: "新疆",
    71: "台湾",
    81: "香港",
    82: "澳门",
    91: "国外 "
  };
  //15位身份证
  let isIDCard15 = /^\d{6}(18|19|20)?\d{2}(0[1-9]|1[012])(0[1-9]|[12]\d|3[01])(\d)$/;
  //18位身份证
  let isIDCard18 = /^\d{6}(18|19|20)?\d{2}(0[1-9]|1[012])(0[1-9]|[12]\d|3[01])\d{3}(\d|X)$/i;

  // let tip = "";
  let pass = true;

  if (!code || !(isIDCard18.test(code) || isIDCard15.test(code))) {
    // tip = "身份证号格式错误";
    pass = false;
  } else if (!city[code.substr(0, 2)]) {
    // tip = "身份证地址编码错误";
    pass = false;
  } else {
    //18位身份证需要验证最后一位校验位
    if (code.length == 18) {
      code = code.split('');
      //∑(ai×Wi)(mod 11)
      //加权因子
      let factor = [7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2];
      //校验位
      let parity = [1, 0, 'X', 9, 8, 7, 6, 5, 4, 3, 2];
      let sum = 0;
      let ai = 0;
      let wi = 0;
      for (let i = 0; i < 17; i++) {
        ai = code[i];
        wi = factor[i];
        sum += ai * wi;
      }
      let last = parity[sum % 11];
      if (parity[sum % 11] != code[17]) {
        // tip = "身份证校验位(最后一位)错误";
        pass = false;
      }
    }
  }
  // if (!pass) alert(tip);
  return pass;
}

/**
 * 验证护照号码
 * @param {String} code
 * @return {Boolean}
 */
function checkPassport(code) {
  let pass = true;
  if (!code || !/^((1[45]\d{7})|(G\d{8})|(P\d{7})|(S\d{7,8}))?$/.test(code)) {
    pass = false;
  }
  return pass;
}

/**
 * 银行卡号Luhn校验算法
 * luhn校验规则：16位银行卡号（19位通用）:
 * 1.将未带校验位的 15（或18）位卡号从右依次编号 1 到 15（18），位于奇数位号上的数字乘以 2。
 * 2.将奇位乘积的个十位全部相加，再加上所有偶数位上的数字。
 * 3.将加法和加上校验位能被 10 整除。
 * @param {String} bankno 银行卡号
 * @return {Boolean}
 */
function luhnCheck(bankno) {
  let lastNum = bankno.substr(bankno.length - 1, 1); //取出最后一位（与luhn进行比较）

  let first15Num = bankno.substr(0, bankno.length - 1); //前15或18位
  let newArr = new Array();
  for (let i = first15Num.length - 1; i > -1; i--) { //前15或18位倒序存进数组
    newArr.push(first15Num.substr(i, 1));
  }
  let arrJiShu = new Array(); //奇数位*2的积 <9
  let arrJiShu2 = new Array(); //奇数位*2的积 >9

  let arrOuShu = new Array(); //偶数位数组
  for (let j = 0; j < newArr.length; j++) {
    if ((j + 1) % 2 == 1) { //奇数位
      if (parseInt(newArr[j]) * 2 < 9)
        arrJiShu.push(parseInt(newArr[j]) * 2);
      else
        arrJiShu2.push(parseInt(newArr[j]) * 2);
    } else //偶数位
      arrOuShu.push(newArr[j]);
  }

  let jishu_child1 = new Array(); //奇数位*2 >9 的分割之后的数组个位数
  let jishu_child2 = new Array(); //奇数位*2 >9 的分割之后的数组十位数
  for (let h = 0; h < arrJiShu2.length; h++) {
    jishu_child1.push(parseInt(arrJiShu2[h]) % 10);
    jishu_child2.push(parseInt(arrJiShu2[h]) / 10);
  }

  let sumJiShu = 0; //奇数位*2 < 9 的数组之和
  let sumOuShu = 0; //偶数位数组之和
  let sumJiShuChild1 = 0; //奇数位*2 >9 的分割之后的数组个位数之和
  let sumJiShuChild2 = 0; //奇数位*2 >9 的分割之后的数组十位数之和
  let sumTotal = 0;
  for (let m = 0; m < arrJiShu.length; m++) {
    sumJiShu = sumJiShu + parseInt(arrJiShu[m]);
  }

  for (let n = 0; n < arrOuShu.length; n++) {
    sumOuShu = sumOuShu + parseInt(arrOuShu[n]);
  }

  for (let p = 0; p < jishu_child1.length; p++) {
    sumJiShuChild1 = sumJiShuChild1 + parseInt(jishu_child1[p]);
    sumJiShuChild2 = sumJiShuChild2 + parseInt(jishu_child2[p]);
  }
  //计算总和
  sumTotal = parseInt(sumJiShu) + parseInt(sumOuShu) + parseInt(sumJiShuChild1) + parseInt(sumJiShuChild2);

  //计算luhn值
  let k = parseInt(sumTotal) % 10 == 0 ? 10 : parseInt(sumTotal) % 10;
  let luhn = 10 - k;

  if (lastNum == luhn) {
    console.log("验证通过");
    return true;
  } else {
    layer.msg("银行卡号必须符合luhn校验");
    return false;
  }
}

/**
 * 检查银行卡号
 * @param {String} bankNum
 * @return {Boolean}
 */
function CheckBankNo(bankNum) {
  let bankno = bankNum.replace(/\s/g, '');
  if (bankno == "") {
    layer.msg("请填写银行卡号");
    return false;
  }
  if (bankno.length < 16 || bankno.length > 19) {
    layer.msg("银行卡号长度必须在16到19之间");
    return false;
  }
  let num = /^\d*$/; //全数字
  if (!num.exec(bankno)) {
    layer.msg("银行卡号必须全为数字");
    return false;
  }
  //开头6位
  let strBin = "10,18,30,35,37,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,58,60,62,65,68,69,84,87,88,94,95,98,99";
  if (strBin.indexOf(bankno.substring(0, 2)) == -1) {
    layer.msg("银行卡号开头6位不符合规范");
    return false;
  }
  //Luhn校验
  if (!luhnCheck(bankno)) {
    return false;
  }
  return true;
}

/**
 * 删除对象空属性
 * @param {Object} param
 * @return {Object}
 */
export const deleteEmpty = function (param) {
  for (let key in param) {
    if (param[key] + '' !== '0') {
      if (!param[key] || param[key].length === 0 || param[key] === 'A') {
        delete param[key];
      } else {
        param[key].join ? param[key] = param[key].join(',') : '';
      }
    }
  }
  return param;
};

/**
 * 格式化时间
 * @param {Date} time
 * @param {String} fmt 格式eg: yyyy-MM-dd HH:mm:ss / yyyy年MM月dd日 EEE HH:mm:ss / EE(周一) / EEE(星期一)
 * @param {Boolean} fix 是否计算本地时间与GMT时间的时间差
 * @return {String} 返回fmt格式
 */
export const formatDate = (time, fmt, fix) => {
  let week = {
    '0': '日',
    '1': '一',
    '2': '二',
    '3': '三',
    '4': '四',
    '5': '五',
    '6': '六'
  };
  let offSet = 60 * 1000 * (new Date(0)).getTimezoneOffset();
  let date = null;
  offSet = !fix ? 0 : offSet;
  if (time instanceof Date) {
    date = time;
  } else {
    date = new Date(+time + offSet);
  }
  let o = {
    'M+': date.getMonth() + 1, // 月份
    'd+': date.getDate(), // 日
    'h+': (date.getHours() % 12) === 0 ? 12 : (date.getHours() % 12), // 小时
    'H+': date.getHours(), // 小时
    'm+': date.getMinutes(), // 分
    's+': date.getSeconds(), // 秒
    'q+': Math.floor((date.getMonth() + 3) / 3), // 季度
    'S': date.getMilliseconds() // 毫秒
  };
  if (/(y+)/.test(fmt)) {
    fmt = fmt.replace(RegExp.$1, (date.getFullYear() + '').substr(4 - RegExp.$1.length))
  }
  if (/(E+)/.test(fmt)) {
    fmt = fmt.replace(RegExp.$1, ((RegExp.$1.length > 1) ? (RegExp.$1.length > 2 ? '星期' : '周') : '') + week[date.getDay() + ''])
  }
  for (let k in o) {
    if (new RegExp('(' + k + ')').test(fmt)) {
      fmt = fmt.replace(RegExp.$1, (RegExp.$1.length === 1) ? (o[k]) : (('00' + o[k]).substr(('' + o[k]).length)))
    }
  }
  return fmt;
};

/**
 * 将秒转换为时间
 * @param {String} sec 秒
 * @return {String} hh:mm:ss
 */
export const convertSecondToTime = sec => {
  if (sec === 0) {
    return sec;
  }
  let hh = 0;
  let mm = 0;
  let ss = 0;
  const step = 60;
  const fix = t => {
    return t < 10 ? '0' + t : t + '';
  };
  const timeOffset = (t, step) => {
    return [Math.floor(t / step), t % step];
  };
  [mm, ss] = timeOffset(sec, step);
  if (mm > 59) {
    [hh, mm] = timeOffset(mm, step);
  }
  return [fix(hh), fix(mm), fix(ss)].join(':');
};

/**
 * 数组去重
 * @param {Array} arr
 * @return {Array}
 */
function removeRepea(arr) {
  let newArr = [],
    json = {};
  for (let i = 0; i < arr.length; i++) {
    if (!json[arr[i]]) {
      json[arr[i]] = 1;
      newArr.push(arr[i]);
    }
  }
  return newArr
}

/**
 * 根据最里层子元素的某个属性获取其父级某个属性的集合
 * @param {Array} array
 * @param {String} childAttr 最里层子元素的属性值
 * @param {String} attrName 匹配的属性名
 * @param {String} parentAttrName 需返回的父级属性名
 * @return {Array} 父级集合
 */
export const getParents = (array, childAttr, attrName, parentAttrName) => {
  let stack = [];
  let going = true;
  let walker = (array, childAttr) => {
    array.forEach(item => {
      if (!going) return;
      stack.push(item[parentAttrName]);
      if (item[attrName] === childAttr) {
        going = false;
      } else if (item['children']) {
        walker(item['children'], childAttr);
      } else {
        stack.pop();
      }
    });
    if (going) stack.pop();
  };
  walker(array, childAttr);
  return stack;
};

/**
 * 根据某个属性获取其它属性
 * @param {Array} data
 * @param {String} attrVal
 * @param {String} attrName
 * @param {String} needAttr 需要的属性的名
 * @return {String} 返回需要的属性值
 */
export const getCurrentData = (data, attrVal, attrName, needAttr) => {
  let name = "";
  let walker = (data, attrVal) => {
    data.forEach(item => {
      if (item[attrName] === attrVal) {
        name = item[needAttr];
      } else if (item['children']) {
        walker(item['children'], attrVal);
      }
    });
  };
  walker(data, attrVal);
  return name;
};
